package modele;

import java.io.Writer;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
import java.util.List;


public class FicheImpl extends UnicastRemoteObject implements Fiche {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	Dossier me;
	int indiceChoix;
	boolean absente; // elle est dans la liste, mais n'est pas renseignee
	Parcours parcours;
	List<UniteEnseignement> uesChoix1, uesChoix2;

	public FicheImpl(Dossier dos, Parcours par) throws Exception {
		me = dos;
		indiceChoix = 0;
		absente = false;
		parcours = par;
		uesChoix1 = new ArrayList<UniteEnseignement>();
		uesChoix2 = new ArrayList<UniteEnseignement>();
	}

	// pour faire un clone de la fiche
	public FicheImpl(Fiche fic) throws Exception {
		me = fic.getDossier();
		absente = fic.getAbsente();
		indiceChoix = fic.getIndiceChoix();
		parcours = fic.getParcours();
		uesChoix1 = new ArrayList<UniteEnseignement>();
		for (UniteEnseignement ue : fic.getUesChoix1())
			uesChoix1.add(ue);
		uesChoix2 = new ArrayList<UniteEnseignement>();
		for (UniteEnseignement ue : fic.getUesChoix2())
			uesChoix2.add(ue);
	}

	// les assesseurs
	public Dossier getDossier() throws Exception {
		return me;
	}
	public boolean getAbsente() throws Exception {
		return absente;
	}
	public Parcours getParcours() throws Exception {
		return parcours;
	}

	public List<UniteEnseignement> getUesChoix1() throws Exception {
		return uesChoix1;
	}

	public List<UniteEnseignement> getUesChoix2() throws Exception {
		return uesChoix2;
	}

	public int getIndiceChoix() throws Exception {
		return indiceChoix;
	}

	public void setAbsente(Boolean b) throws Exception {
		absente = b;
	}

	public void setIndiceChoix(int c) throws Exception {
		indiceChoix = c;
	}

	public void setParcours(Parcours par) throws Exception {
		parcours = par;
	}

	private void setUesChoix1(String[] ues) throws Exception {
		uesChoix1.clear();
		for (int i=0; i<ues.length; i++) {
			UniteEnseignement ue =
				me.getBd().getUniteEnseignement(new Integer(ues[i]));
			if (uesChoix1.indexOf(ue) == -1)
				uesChoix1.add(ue);
		}
	}

	private void setUesChoix2(String[] ues) throws Exception {
		uesChoix2.clear();
		for (int i=0; i<ues.length; i++) {
			UniteEnseignement ue =
				me.getBd().getUniteEnseignement(new Integer(ues[i]));
			if (uesChoix2.indexOf(ue) == -1)
				uesChoix2.add(ue);
		}
	}

	// les algos
	public Integer[][] getUesDemandeesIdent() throws Exception {
		Integer[][] aux = new Integer[2][];
		aux[0] = new Integer[parcours.getUeChoix1().size()];
		aux[1] = new Integer[parcours.getUeChoix2().size()];
		for (int i=0; i<aux[0].length; i++)
			aux[0][i] = ((UniteEnseignement)(parcours.getUeChoix1().first())).
			getIdent();
		for (int i=0; i<aux[1].length; i++)
			aux[1][i] = ((UniteEnseignement)(parcours.getUeChoix2().first())).
			getIdent();
		int indC=0;
		for (UniteEnseignement ue : uesChoix1) {
			aux[0][indC] = ue.getIdent();
			indC++;
		}
		int indL=0;
		for (UniteEnseignement ue : uesChoix2){
			aux[1][indL] = ue.getIdent();
			indL++;
		}
		return aux;
	}

	public void record(String[][] ues) throws Exception {
		setUesChoix1(ues[0]);
		setUesChoix2(ues[1]);
	}

	public boolean[] evaluer() throws Exception {
		// b[0] : fiche complete
		// b[1] : fiche valide
		boolean[] b = new boolean[2];
		// parcours TMP -> toujours valide
		if (parcours != null &&
				(parcours.getSigle().startsWith("Enseirb")|
						parcours.getSigle().startsWith("Non"))) {
			b[0] = true;
			b[1] = true;
		}
		else if (absente) {
			b[0] = false;
			b[1] = false;
		}
		else if ((uesChoix1.size() < parcours.getNbUeChoix1()) | (uesChoix2.size() < parcours.getNbUeChoix2())) {
			b[0] = false;
			b[1] = false;
		}
		else if ((uesChoix1.size()<(parcours.getUeChoix1().size() -1)) |
				(uesChoix2.size()<parcours.getUeChoix2().size())) {
			b[0] = false;
			b[1] = true;
		}
		else {
			b[0] = true;
			b[1] = true;
		}
		return b;
	}

	public boolean equals(Fiche fic) throws Exception {
		boolean idem = (me == fic.getDossier() &&
				absente == fic.getAbsente() &&
				indiceChoix == fic.getIndiceChoix() &&
				parcours == fic.getParcours() &&
				uesChoix1.size() == fic.getUesChoix1().size() &&
				uesChoix2.size() == fic.getUesChoix2().size());
		if (idem) {
			for (int i=0; i<uesChoix1.size() & idem; i++)
				idem &= (uesChoix1.get(i)==fic.getUesChoix1().get(i));
			for (int i=0; i<uesChoix2.size() & idem; i++)
				idem &= (uesChoix2.get(i)==fic.getUesChoix2().get(i));
		}
		return idem;
	}

	/** Mise a jour des liens Parcours et UEs
	 *  remove si b est faux
	 *  add si b est vrai
	 *  les liens Ues ne concernent que la fiche du premier choix
	 **/
	public void setLiensParUes(boolean b) throws Exception {
		if (b) {
			parcours.addDemande(this);
			if (indiceChoix==0) {
				for (UniteEnseignement ue : parcours.getUeObligatoires())
					ue.addDemande(me);
				for (UniteEnseignement ue : uesChoix1)
					ue.addDemande(me);
				for (UniteEnseignement ue : uesChoix2)
					ue.addDemande(me);
			}
		}
		else {
			parcours.removeDemande(this);
			if (indiceChoix==0) {
				for (UniteEnseignement ue : parcours.getUeObligatoires())
					ue.removeDemande(me);
				for (UniteEnseignement ue : uesChoix1)
					ue.removeDemande(me);
				for (UniteEnseignement ue : uesChoix2)
					ue.removeDemande(me);
			}
		}
	}

	// les sorties
	public void imprimer(Writer file) throws Exception {
		boolean[] b = evaluer();
		file.write("\\nopagebreak&&&"+parcours.toString());
		/**
	if (!b[0])
	    file.write("\\hspace{\\fill}nC ");
		 **/
		if (!b[1])
			file.write("\\hspace{\\fill}NV ");
		file.write("&"+uesChoix1.toString()+"&"+uesChoix2.toString()+"\\\\\n");
	}

	public void imprimerCourrier(Writer file) throws Exception {
		boolean[] cv = evaluer();
		file.write("\\caption*{Parcours "+parcours.getIntitule()+"}\\\\\n");
		if (cv[1]) { // fiche valide
			int max;
			if (uesChoix1.size() > uesChoix2.size())
				max = uesChoix1.size();
			else
				max = uesChoix2.size();
			if (max > 0) {
				String[][] aux = new String[2][max];
				int ind = 0;
				if (uesChoix1.size() > 0) {
					for (UniteEnseignement ue : uesChoix1){
						aux[0][ind] = ue.getIntitule();
						ind++;
					}
				}
				for(int i=ind; i<max; i++)
					aux[0][i] = new String(" ");
				ind = 0;
				if (uesChoix2.size() > 0) {
					for (UniteEnseignement ue : getUesChoix2()){
						aux[1][ind] = ue.getIntitule();
						ind++;
					}
				}
				for(int i=ind; i<max; i++)
					aux[1][i] = new String(" ");
				for(int i=0; i<max; i++)
					file.write(aux[0][i]+"&"+aux[1][i]+"\\\\\n");
			}
		}
		else { // fiche invalide
			file.write("\\caption*{Fiche absente ou incompl\\`ete}\\\\\n");
		}
		file.write("\\hline\\\\\n");
	}

	public void imprimerDossier(Writer file, int ind) throws Exception {
		boolean[] cv = evaluer();
		file.write("Choix num\\'ero "+ind+
				"&&{\\bf Parcours "+parcours.getIntitule()+"}\\\\\n");
		boolean nb=true;
		for (UniteEnseignement ue : parcours.getUeObligatoires()){
			if (nb)
				file.write("&Unit\\'es obligatoires&"+ue.getIntitule()+"\\\\\n");
			else
				file.write("&&"+ue.getIntitule()+"\\\\\n");
			nb=false;
		}
		nb = true;
		for (UniteEnseignement ue : uesChoix1) {
			if (nb)
				file.write("&Unit\\'es au choix 1&"+ue.getIntitule()+"\\\\\n");
			else
				file.write("&&"+ue.getIntitule()+"\\\\\n");
			nb=false;
		}
		nb = true;
		for (UniteEnseignement ue : uesChoix2) {
			if (nb)
				file.write("&Unit\\'es choix 2&"+ue.getIntitule()+"\\\\\n");
			else
				file.write("&&"+ue.getIntitule()+"\\\\\n");
			nb=false;
		}
		if (!cv[1]) // fiche invalide
			file.write("\\caption*{\\bf{Attention fiche incompl\\`ete "+
					"qui ne peut pas \\^etre retenue}}"+
			"\\\\\n");
		file.write("\\hline\n");
	}

}
